package com.ruoyi.web.controller.app.pay.wechat.service.impl;

import com.ruoyi.web.controller.app.pay.util.NewsAddressUtils;
import com.ruoyi.web.controller.app.pay.util.PayUtil;
import com.ruoyi.web.controller.app.pay.wechat.service.IWeixinPayService;
import com.ruoyi.web.controller.app.pay.wechat.util.ConfigUtil;
import com.ruoyi.web.controller.app.pay.wechat.util.HttpUtil;
import com.ruoyi.web.controller.app.pay.wechat.util.PayCommonUtil;
import com.ruoyi.web.controller.app.pay.wechat.util.XMLUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xml.sax.SAXException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.DecimalFormat;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

@Service
public class WeixinPayServiceImpl implements IWeixinPayService {
	private static final Logger logger = LoggerFactory.getLogger(WeixinPayServiceImpl.class);

	@Value("${wexinpay.notify.url}")
	private String notify_url;

	/*@Autowired
	private OrderMapper orderMapper;

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private OrderGoodsMapper orderGoodsMapper;

	@Autowired
	private StoreAccountMapper storeAccountMapper;
	@Autowired
	private FlowMapper flowMapper;

	@Autowired
	private CategoryMapper categoryMapper;
	@Autowired
	private StoreMapper storeMapper;

	@Autowired
	private CarMapper carMapper;
*/
	private DecimalFormat df = new DecimalFormat("0.00");


	@Override
	public Map appPay(String uid, Long orderId,HttpServletRequest request) throws IOException, JDOMException {
//		//随机字符串

	//1、	Order order = orderMapper.selectById(orderId);
//
		//1、double money =  CommonUtil.getNewDouble(order.getPayMoney(), 2);

		String key = ConfigUtil.API_KEY; // key
		SortedMap<Object, Object> packageParams = new TreeMap<>();
		ConfigUtil.commonParams(packageParams);
		String body = "微信支付";
		packageParams.put("body", new String(body.getBytes("utf-8"),"utf-8"));// 商品描述
		packageParams.put("attach",uid);
		//1、packageParams.put("out_trade_no", order.getOrderNo());// 商户订单号
		//1、Integer totalFee=(int)(money*100);
		//1、packageParams.put("total_fee",String.valueOf(totalFee));// 总金额
		packageParams.put("spbill_create_ip", NewsAddressUtils.getIpAddr(request));// 发起人IP地址
		packageParams.put("notify_url",notify_url);// 回调地址
		packageParams.put("trade_type", "APP");// 交易类型
		String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);

		packageParams.put("sign", sign);// 签名
		String requestXML = PayCommonUtil.getRequestXml(packageParams);
		String resXml = HttpUtil.postData(ConfigUtil.UNIFIED_ORDER_URL, requestXML);
		Map map = XMLUtil.doXMLParse(resXml);
		String returnCode = (String) map.get("return_code");
		if("SUCCESS".equals(returnCode)){
			String resultCode = (String) map.get("result_code");
			if("SUCCESS".equals(resultCode)){
				String prepayId = (String)map.get("prepay_id");
				String nonce_str = UUID.randomUUID().toString().replaceAll("-", "");
				//SortedMap<Object, Object> payParams = new TreeMap<Object, Object>();
				packageParams.clear();
				packageParams.put("appid", ConfigUtil.APP_ID);
				packageParams.put("partnerid", ConfigUtil.MCH_ID);
				packageParams.put("prepayid",prepayId);
				packageParams.put("package","Sign=WXPay"); //暂填写固定值Sign=WXPay
				packageParams.put("noncestr",nonce_str);
				packageParams.put("timestamp",""+System.currentTimeMillis()/1000);
				String pay_sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
				packageParams.put("sign",pay_sign);
				return packageParams;
			}else{
				String errCodeDes = (String) map.get("err_code_des");
				throw new IllegalArgumentException(errCodeDes);

			}
		}else{
			String returnMsg = (String) map.get("return_msg");
			throw new IllegalArgumentException(returnMsg);
		}
	}



	@Override
	@Transactional(rollbackFor = RuntimeException.class)
	public void notifyUrl(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, SAXException {
		//解析对方发来的xml数据
		System.out.println("进入微信回调>>>>>>>>>>>>>>>");
		SAXReader sax=new SAXReader();//创建一个SAXReader对象
		sax.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

		//sax.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);

		// 是否包含外部生成的实体。当正在解析文档时为只读属性，未解析文档的状态下为读写。
		sax.setFeature("http://xml.org/sax/features/external-general-entities", false);

		// 是否包含外部的参数，包括外部DTD子集。当正在解析文档时为只读属性，未解析文档的状态下为读写。
		sax.setFeature("http://xml.org/sax/features/external-parameter-entities", false);

		sax.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
		Document document;
		try {
			document = sax.read(request.getInputStream());
			Map<String, String> map2 = PayUtil.parseXml(document.asXML());
			String attach = map2.get("attach");
			String result_code = map2.get("result_code");
			String out_trade_no = map2.get("out_trade_no"); //订单号
			//String total_fee = map2.get("total_fee");
			String return_code = map2.get("return_code");
			String appid = map2.get("appid");
			String mch_id = map2.get("mch_id");
			String cash_fee = map2.get("cash_fee");
			//处理签名验证
			String sign = map2.get("sign");
			map2.remove("sign"); //移除sign
			final TreeMap<String, String> map = new TreeMap<String, String>();
			map2.forEach((k,v)->{
				map.put(k, v);
			});
			int temp=0;
			String mysing  =  PayUtil.getPaySign(map, ConfigUtil.API_KEY);
			if (mysing.equals(sign) && mch_id.equals(ConfigUtil.MCH_ID) && appid.equals(ConfigUtil.APP_ID)) { //签名效验成功
				System.out.println("微信回调验证通过>>>>>>>>>>>>>>>");
			/*	1、Order order = orderMapper.selectByOrderNo(out_trade_no);
				double money = order.getPayMoney();*/
				String[] STR =  attach.split(","); //业务主键 /业务类型 // 用户ID
				//1、int mone  =   (int)(money*100);
				/*if (result_code.equals("SUCCESS") && return_code.equals("SUCCESS") && cash_fee.equals(mone+"")) {
					//增加用户积分，增加商家余额，修改订单状态,增加流水
//					UserInfoEntity userInfoEntity=userInfoMapper.selectById(STR[0]);
//					List<Map<String,Object>> list=orderGoodsMapper.selectByOrderId(order.getId());
//					Integer integral=0;
//					if(!list.isEmpty()){
//						for(Map<String,Object> map1:list){
//							integral+=Integer.valueOf(map1.get("integral").toString());
//						}
//					}
//
//					//增加积分
//					int jifen = userInfoEntity.getSpare()!=null?(Integer.parseInt(userInfoEntity.getSpare())+integral):integral;
//					userInfoEntity.setSpare(jifen+"");
//					userInfoEntity.preUpdate();
//					userInfoMapper.updateById(userInfoEntity);

					//增加余额  余额计算要有如下步骤
					double lastMoney = money;
					double pt = 0.00;
					double zhib = Double.parseDouble(df.format(money * 0.01));
					// 1,减去商户平台费  并加入流水
					Store store = storeMapper.selectById(order.getStoreId());
					MallCategory mallCategory = categoryMapper.selectParentInfoById(store.getStoreType());
					if(mallCategory!=null && mallCategory.getWxzfbCharge()!=null){
						pt = lastMoney * (mallCategory.getWxzfbCharge() / 100);
						if(pt>0){
							lastMoney = lastMoney - pt;
						}
					}
					// 2,减去智贝抵扣费用 并加入流水  智贝抵扣费用=订单商品金额*0.01
					if(zhib>0){
						lastMoney = lastMoney - zhib;
					}
					lastMoney = Double.parseDouble(df.format(lastMoney));

					StoreAccount storeAccount=storeAccountMapper.selectByStoreId(order.getStoreId());
					storeAccount.setMoney(storeAccount.getMoney()!=null?(storeAccount.getMoney()+lastMoney):lastMoney);
					storeAccountMapper.updateById(storeAccount);

					//修改订单状态
					order.setOrderType(OrderTypeEnum.DJD.getCode());
					order.preUpdate();
					order.setPayTime(new Date());
					orderMapper.updateById(order);
					String flowNo=String.valueOf(System.currentTimeMillis()/1000)+order.getStoreId().toString();
					//增加流水  订单交易
					Flow flow=Flow.builder().flowNo(flowNo)
							.money(money).orderId(order.getId()).type(1)
							.storeId(order.getStoreId()).title("购物商品").build();
					flow.setRemark("订单交易");
					flow.preInsert();
					flowMapper.insert(flow);

					//增加流水 平台使用费
					if(pt>0){
						pt = Double.parseDouble(df.format(pt));
						String flowNo1=String.valueOf(System.currentTimeMillis()/1000)+order.getStoreId().toString();
						Flow flow1=Flow.builder().flowNo(flowNo1)
								.money(pt).orderId(order.getId()).type(2)
								.storeId(order.getStoreId()).title("平台使用费").build();
						flow1.setRemark("平台使用费");
						flow1.preInsert();
						flowMapper.insert(flow1);
					}

					//增加流水 智贝积分抵扣费
					if(zhib>0){
						String flowNo2=String.valueOf(System.currentTimeMillis()/1000)+order.getStoreId().toString();
						Flow flow2=Flow.builder().flowNo(flowNo2)
								.money(zhib).orderId(order.getId()).type(2)
								.storeId(order.getStoreId()).title("智贝积分抵扣").build();
						flow2.setRemark("智贝积分抵扣费用");
						flow2.preInsert();
						flowMapper.insert(flow2);
					}*/

					//删除购物车
				/*	1、if(!StringUtils.isEmpty(order.getCarIds())){
						String[] cardIdArray=order.getCarIds().split(",");
						carMapper.deleteByIds(cardIdArray);
					}*/

					temp=1;
				}

			//}
			//验证成功
			if (temp>0) { //更新订单状态
				map2.clear();
				map2.put("return_code", "SUCCESS");
				map2.put("return_msg", "OK");

			}else {
				map2.put("return_code", "FAIL");
				map2.put("return_msg", "FAIL");
			}
			//处理后同步返回给微信参数
			PrintWriter pw = response.getWriter();
			String str =   PayUtil.ConvertedMapToXml(map2);
			pw.println(str);
			pw.close();
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
